package com.cncqs.generator;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @author: cxy
 * @date: 2019/4/10 0010 上午 10:49
 */
public class MybatisPlusGenerator {

    private Logger logger = LoggerFactory.getLogger(MybatisPlusGenerator.class);
    //private String baseDir = "/Users/yandou/java/workspace/invmanager";
    private String baseDir = "F:/code/eat/fronted";
    private String outputDir = baseDir + "/src/main/java/";
    private String jsputDir = baseDir + "/src/main/resources/static/bizjs/";
    private String ftlputDir = baseDir + "/src/main/resources/templates/";
    private String xmlputDir = baseDir + "/src/main/resources/mapper/";
    private String packageName = "com.cncqs";
    //tticar
//    private String xmlputDir = baseDir + "/src/main/resources/mapper/tticar/";
//    private String packageName = "com.tticar.invmanager.tticar";

    private PackageConfig packageConfig;
    private DataSourceConfig dataSourceConfig;
    private StrategyConfig strategyConfig;
    private GlobalConfig globalConfig;

    /**
     * isJustEntity 只更新实体
     * noController 是否生成controller
     */
    private String tjson = "[\n" +

//                      "  , {tname:'applet_user',isJustEntity:false,isService:false,isController:true,isPage:false,isSearch:false,isOpt:false,isTree:false}\n" +
                      "  , {tname:'login_validate',isJustEntity:false,isService:false,isController:true,isPage:false,isSearch:false,isOpt:false,isTree:false}\n" +
            "]";

    @Test
    public void generateCode() {
        getDataSourceConfig();
        getStrategyConfig();
        getPackageConfig();
        getGlobalConfig();

        JSONArray tbs = JSONArray.parseArray(tjson);
        generateByTables(tbs);
    }

    private void generateByTables(JSONArray models) {
        AutoGenerator mpg = new AutoGenerator();
        mpg.setTemplateEngine(new MyFreemarkerTemplateEngine());
        mpg.setDataSource(dataSourceConfig);
        mpg.setStrategy(strategyConfig);
        mpg.setPackageInfo(packageConfig);
        mpg.setGlobalConfig(globalConfig);
        mpg.setCfg(new InjectionConfig() {
            @Override
            public void initMap() {
                setMap(null);
            }
        });

        for (Object model : models) {
            mpg.setConfig(null);
            JSONObject tb = (JSONObject) model;
            mpg.getStrategy().setInclude(tb.get("tname").toString());
            logger.info("#table={}", mpg.getStrategy().getInclude()[0].toString());
            boolean isJustEntity = tb.getBoolean("isJustEntity"); //  生成entity
            boolean isService = tb.getBoolean("isService"); //生成 service/servcieImpl/mapper/xml/entity
            boolean isController = tb.getBoolean("isController"); //生成 /controller/service/servcieImpl/mapper/xml/entity
            boolean isPage = tb.getBoolean("isPage"); //生成 /ftl/controller/service/servcieImpl/mapper/xml/entity
            Map map = new HashMap();
            map.put("isTree", isPage && tb.getBoolean("isTree"));
            map.put("isSearch", isPage && tb.getBoolean("isSearch"));
            map.put("isOpt", isPage && tb.getBoolean("isOpt"));
            map.put("isService", isService);

            mpg.setCfg(new InjectionConfig() {
                @Override
                public void initMap() {
                    setMap(map);
                }
            });

            mpg.setTemplate(getTemplateConfig(isJustEntity, isService, isController));

//            mpg.getCfg().setFileOutConfigList(getDefault(tb));生成ftl文件 暂不需要

            mpg.execute();
        }
    }

    private TemplateConfig getTemplateConfig(boolean isJustEntity, boolean isService, boolean isController) {
        // 关闭默认 xml 生成，调整生成 至 根目录
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setXml(null);
        templateConfig.setEntity("/templates/temp/entity.java");
        templateConfig.setController("/templates/temp/controller.java");
        templateConfig.setService("/templates/temp/service.java");
        templateConfig.setServiceImpl("/templates/temp/serviceImpl.java");
        templateConfig.setMapper("/templates/temp/mapper.java");
        if (isJustEntity) {
            templateConfig.setController(null);
            templateConfig.setService(null);
            templateConfig.setServiceImpl(null);
            templateConfig.setMapper(null);
            return templateConfig;
        }
        if (isService) {
            templateConfig.setController(null);
            return templateConfig;
        }
        return templateConfig;
    }

    private List<FileOutConfig> getDefault(JSONObject tb) {
        boolean isJustEntity = tb.getBoolean("isJustEntity");
        boolean isService = tb.getBoolean("isService");
        boolean isController = tb.getBoolean("isController");
        boolean isPage = tb.getBoolean("isPage");

        List<FileOutConfig> focList = new ArrayList();
        if (isJustEntity) {
            return focList;
        }
        if (isService) {
            focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
                @Override
                public String outputFile(TableInfo tableInfo) {
                    return xmlputDir + tableInfo.getEntityName() + "Mapper.xml";
                }
            });
            return focList;
        }

        if (!isJustEntity && !isService && isController && isPage) {
            focList.add(new FileOutConfig("/templates/js.js.ftl") {
                @Override
                public String outputFile(TableInfo tableInfo) {
                    return jsputDir + tableInfo.getEntityPath() + ".js";
                }
            });
            focList.add(new FileOutConfig("/templates/html.ftl.ftl") {
                @Override
                public String outputFile(TableInfo tableInfo) {
                    String bpackage = ftlputDir + tableInfo.getEntityPath();
                    return bpackage + File.separator + tableInfo.getEntityPath() + ".ftl";
                }
            });
            focList.add(new FileOutConfig("/templates/html_edit.ftl.ftl") {
                @Override
                public String outputFile(TableInfo tableInfo) {
                    String bpackage = ftlputDir + tableInfo.getEntityPath();
                    return bpackage + File.separator + tableInfo.getEntityPath() + "_edit.ftl";
                }
            });
        }
        return focList;
    }

    private void getGlobalConfig() {
        globalConfig = new GlobalConfig();
        globalConfig.setActiveRecord(false);
        globalConfig.setAuthor("cxy");
        globalConfig.setOutputDir(outputDir);
        globalConfig.setEnableCache(false);
        globalConfig.setOpen(false);
        globalConfig.setFileOverride(true);
    }

    private void getPackageConfig() {
        packageConfig = new PackageConfig();
        packageConfig.setParent(packageName);
        packageConfig.setController("controller");
    }

    private void getDataSourceConfig() {
        dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL);
        dataSourceConfig.setUrl("jdbc:mysql://127.0.0.1:3306/lightful_kitchen?serverTimezone=GMT%2B8");
        dataSourceConfig.setUsername("root");
        dataSourceConfig.setPassword("123456");
//        dataSourceConfig.setUrl("jdbc:mysql://localhost/tticar_invmgr");
//        dataSourceConfig.setUsername("root");
////        dataSourceConfig.setPassword("");
        dataSourceConfig.setDriverName("com.mysql.jdbc.Driver");
    }

    private void getStrategyConfig() {
        strategyConfig = new StrategyConfig();
        strategyConfig.setCapitalMode(true);
        strategyConfig.setEntityLombokModel(false);
        strategyConfig.setDbColumnUnderline(true);
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setSuperControllerClass("com.cncqs.controller.BaseController");
        strategyConfig.setEntityColumnConstant(true);
        strategyConfig.entityTableFieldAnnotationEnable(true);
        strategyConfig.setSuperEntityClass("com.cncqs.base.BaseEntity");
//        strategyConfig.setSuperEntityColumns("id", "tenant_id", "ctime", "utime");
        strategyConfig.setSuperEntityColumns("id", "create_time", "update_time");
    }
}